package it.gtd.swimpool.controller.resources;


import it.gtd.swimpool.model.business.SkillManager;
import it.gtd.swimpool.model.entity.Administrator;
import it.gtd.swimpool.model.entity.Skill;
import it.gtd.swimpool.model.entity.SuperUser;
import it.gtd.swimpool.model.entity.User;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.Collection;
import java.util.List;

@Stateless
@Path("/")
public class SkillResource extends SecuredResource {
    @PersistenceContext
    private EntityManager entityManager;

    @EJB
    private SkillManager skillManager;


    @GET
    @Path("/skills")
    @Produces(MediaType.APPLICATION_JSON)
    public Collection<Skill> getAllSkills() {
        List<Skill> skills = entityManager.createNamedQuery("Skill.all", Skill.class).getResultList();
        return skills;
    }

    @GET
    @Path("/self/skills")
    @Produces(MediaType.APPLICATION_JSON)
    public Collection<Skill> getOwnSkills(
        @CookieParam(Cookie.SESSION_ID) String sessionId
    ) {
        return entityManager.createNamedQuery("User.bySessionId", User.class).
                setParameter("session_id", sessionId).getSingleResult().getSkills();
    }

    @GET
    @Path("/users/{id}/skills")
    @Produces(MediaType.APPLICATION_JSON)
    public Collection<Skill> getUserSkills(
        @PathParam("id") int id
    ) {
        return entityManager.find(User.class, id).getSkills();
    }

    @GET
    @Path("/skills/proposals")
    @Produces(MediaType.APPLICATION_JSON)
    public List<Skill> getSkillProposals(
        @CookieParam(Cookie.SESSION_ID) String sessionId,
        @QueryParam("start") @DefaultValue("0") int start,
        @QueryParam("end")   @DefaultValue("20") int size
    ) {
        checkAdministrator(sessionId);

        return skillManager.getProposals();
    }

    @PUT
    @Path("/self/skills/{id}")
    public void addSkillToSelf(
        @CookieParam(Cookie.SESSION_ID) String sessionId,
        @PathParam("id") int id
    ) {
        User caller = checkUser(sessionId);
        Skill skill = entityManager.find(Skill.class, id);

        skillManager.add(caller,  skill);
    }

    @DELETE
    @Path("/skills/proposals/{sid}")
    public void deleteSkillProposal(
        @CookieParam(Cookie.SESSION_ID) String sessionId,
        @PathParam("sid") int id,
        @QueryParam("accepted") boolean accepted
    ) {
        Administrator admin = checkAdministrator(sessionId);

        Skill skill = entityManager.find(Skill.class, id);

        if (accepted) {
            skillManager.approve(admin, skill);
        } else {
            skillManager.decline(admin, skill);
        }
    }

    @POST
    @Path("/skills/proposals")
    @Consumes(MediaType.APPLICATION_JSON)
    public void proposeNewSkill(
        @CookieParam(Cookie.SESSION_ID) String sessionId,
        Skill proposedSkill
    ) {
        User caller = checkUser(sessionId);
        Skill skill = new Skill();

        skill.setName(proposedSkill.getName());
        skill.setDescription(proposedSkill.getDescription());

        if ((caller instanceof Administrator) || (caller instanceof SuperUser)) {
            skillManager.declare((Administrator)caller, skill);
        } else {
            skillManager.propose(caller, skill);
        }
    }

    @DELETE
    @Path("/skills/{id}")
    public void deleteSkill(
        @CookieParam(Cookie.SESSION_ID) String sessionId,
        @PathParam("id") int id
    ) {
        checkSuperUser(sessionId);

        Skill skill = entityManager.find(Skill.class, id);
        entityManager.remove(skill);
    }

    @DELETE
    @Path("/self/skills/{id}")
    public void removeSkillFromSelf(
        @CookieParam(Cookie.SESSION_ID) String sessionId,
        @PathParam("id") int id
    ) {
        skillManager.remove(checkUser(sessionId), entityManager.find(Skill.class, id));
    }

    @DELETE
    @Path("/users/{id}/skills/{sid}")
    public void removeSkillFromUser(
        @CookieParam(Cookie.SESSION_ID) String sessionId,
        @PathParam("id") int id,
        @PathParam("sid") int sid
    ) {
        User caller = checkSuperUser(sessionId);

        skillManager.remove(
            entityManager.find(User.class, id),
            entityManager.find(Skill.class, sid)
        );
    }
}
